/*
 * Copyright (C) 2005, Velocityme Partnership
 * LicenceManager.java
 *
 * Created on 25 June 2005, 10:03
 */

package com.velocityme.utility;

import com.velocityme.entity.LoginStatusBean;
import com.velocityme.interfaces.*;
import java.util.*;
import javax.ejb.*;
import javax.naming.NamingException;
import org.apache.log4j.Logger;

/**
 *
 * @author  Robert
 */
public class LicenceManager {
    
    //private static final long m_logoutDelay = 10 * 60 * 1000; // 10 minutes
    private static final long m_logoutDelay = 60 * 60 * 1000; // 1 hour
    
    private LoginStatusLocal m_loginStatusReset;
    private LoginStatusLocal m_loginStatusLoggedOff;
    private LoginStatusLocal m_loginStatusTimedOut;
    private LoginStatusLocal m_loginStatusLicenceExpired;

    static private LicenceManager m_managerInstance = null;
    
    private static final Logger m_log = Logger.getLogger(LicenceManager.class);

    /** Creates a new instance of LicenceManager */
    private LicenceManager() {
        if (!closeCurrentSessions())
            m_log.error("Unable to reset unclosed login sessions!");
    }
    
    private LoginStatusLocal getLoginStatus(int status) {
        try {
            return LoginStatusUtil.getLocalHome().findByPrimaryKey(new LoginStatusPK(new Integer(status)));
        } catch(NamingException e) {
            throw new EJBException(e);
        } catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    private LoginStatusLocal getLoginStatusReset() {
        if (m_loginStatusReset == null)
            m_loginStatusReset = getLoginStatus(LoginStatusBean.RESET);
        return m_loginStatusReset;
    }
    
    private LoginStatusLocal getLoginStatusTimedOut() {
        if (m_loginStatusTimedOut == null)
            m_loginStatusTimedOut = getLoginStatus(LoginStatusBean.TIMED_OUT);
        return m_loginStatusTimedOut;
    }
    
    public static LicenceManager getInstance() {
        // keep trying to construct until we get a valid one
        if (m_managerInstance == null)
            m_managerInstance = new LicenceManager();
        m_managerInstance.performTimerTask();
        return m_managerInstance;
    }
    
    public void pingWatchdog(KeySessionLocal p_key) {
        performTimerTask();
    }
    
    private boolean closeCurrentSessions() {
        m_log.info("Close current login sessions");
        try {
            Collection allLoggedOnLocal = LoginUtil.getLocalHome().findAll();
            Iterator i = allLoggedOnLocal.iterator();
            Date logoutTime = new Date();
            while(i.hasNext()) {
                LoginLocal loginLocal = (LoginLocal)i.next();
                loginLocal.setLicenceKeyLocal(null);
                if (loginLocal.isLoggedOn()) {
                    loginLocal.setLogoutTime(logoutTime);
                    loginLocal.setLoginStatusLocal(getLoginStatusReset());
                }
            }
        } catch(NamingException e) {
            return false;
        } catch(FinderException e) {
            return false;
        }
        return true;
    }
    
    private void performTimerTask() {
        try {
            // check for expired sessions
            Date date = new Date();
            try {
                Iterator i = LoginUtil.getLocalHome().findAllLoggedOn().iterator();
                while(i.hasNext()) {
                    LoginLocal loginLocal = (LoginLocal)i.next();
                    if (date.getTime() > loginLocal.getLastActionTime().getTime() + m_logoutDelay) {
                        loginLocal.setLogoutTime(date);
                        loginLocal.setLoginStatusLocal(getLoginStatusTimedOut());
                    }
                }
            } catch(NamingException e) {
                return;
            } catch(FinderException e) {
                return;
            }
        } catch(Exception e) {
            //e.printStackTrace();
            m_log.error("Exception in performTimerTask!", e);
        }
    }
    
}
